#include "shmem.h"
#include <stdio.h>
#include "modbus-tcp.h"
#include "modbus.h"
#include <pthread.h>
#include "cJSON.h"
#include "msg_queue_peer.h"
// 采集数据结构体和共用体
union val
{
    int val_int;
    double val_double;
    int val_bool;
};

struct leixing
{
    int type;
    int period;
};

struct mqtt_server
{
    char addr[128];
    int port;
};

struct mb_dev
{
    char addr[128];
    int port;
};

struct stm32
{
    int key;
    char name[128];  // 数据点名称
    int type;        // 数据点类型
    union val value; // 采集的新数据
};

struct modbus
{
    int key;
    char name[128];  // 数据点名称
    int addr;        // Modbus寄存器地址
    int type;        // 数据点类型
    union val value; // 采集的新数据
};

struct dapeng_date
{
    int stm32_count;
    int modbus_count;
    char vs[128];
    struct leixing lx;
    struct mqtt_server ms;
    struct mb_dev md;
    struct stm32 st[10];
    struct modbus mb[10];
};

// 控制slave数据结构体和共用体
struct kongzhidata
{
    int key;
    char name[128]; // 数据点名称
    int addr;       // 寄存器地址
    // int type;// 数据点类型
    char value[128];   //控制的数据
};

struct dapengkongzhi
{
    long type;//1：采集指令 2：控制指令 3：模式修改 4：历史数据查询
    struct kongzhidata kongzhi;
};

modbus_t *ctx;
struct shm_param sh;
struct dapeng_date *dap_data;
struct dapengkongzhi k_open;

// 采集线程
void *caiji()
{
    
    uint16_t dest[6];
    uint8_t dest2[5];
    shm_init(&sh, "daxaingmugongxiang", sizeof(struct dapeng_date)); // 初始化共享内存
    dap_data = shm_getaddr(&sh);                                     // 创建映射
    // printf("%d\n", dap_data->modbus_count);
    while (1)
    {
        
        modbus_read_registers(ctx, 0, 6, dest);   // 读保持寄存器里的内容存到dest中
        double co2 = modbus_get_float_dcba(dest); // 取寄存器的值
        double o2 = modbus_get_float_dcba(dest + 2);
        double tu = modbus_get_float_dcba(dest + 4);
        modbus_read_bits(ctx, 0, 5, dest2); // 读线圈状态将线圈状态存到dest2
        int open_co2 = dest2[0];
        int open_o2 = dest2[1];
        int open_fun = dest2[2];
        int open_tu = dest2[3];
        int open_fei = dest2[4];

        // dap_data->mb[0].key=101;
        // dap_data->mb[1].key=102;
        // dap_data->mb[2].key=103;
        // dap_data->mb[3].key=104;
        // dap_data->mb[4].key=105;
        // dap_data->mb[5].key=106;
        // dap_data->mb[6].key=107;
        // dap_data->mb[7].key=108;
        
        for (int i = 0; i < 9; i++) // 将取到的值写到共享内存
        {
            // printf("**************************************:%d\n",dap_data->mb->key);
            if (dap_data->mb[i].key == 101) // 根据key值判断上报的消息
            {
  
                dap_data->mb[i].value.val_double = co2;
                printf("二氧化碳 %.2f \n", dap_data->mb[i].value.val_double);
            }
            if (dap_data->mb[i].key == 102)
            {
                // dap_data->mb[i].type = 2;
                dap_data->mb[i].value.val_double = o2;
                printf("氧气 %.2f \n", dap_data->mb[i].value.val_double);
            }

            if (dap_data->mb[i].key == 103)
            {
                // dap_data->mb[i].type = 2;
                dap_data->mb[i].value.val_double = tu;
                printf("土壤 %.2f \n", dap_data->mb[i].value.val_double);
            }

            if (dap_data->mb[i].key == 104)
            {
                // dap_data->mb[i].type = 0;
                dap_data->mb[i].value.val_bool = open_co2;
                printf("二氧化碳控制器开关 %d \n", dap_data->mb[i].value.val_bool);
            }

            if (dap_data->mb[i].key == 105)
            {
                // dap_data->mb[i].type = 0;
                dap_data->mb[i].value.val_bool = open_o2;
                printf("氧气开关 %d \n", dap_data->mb[i].value.val_bool);
            }

            if (dap_data->mb[i].key == 106)
            {
                // dap_data->mb[i].type = 0;
                dap_data->mb[i].value.val_bool = open_fun;
                printf("风机开关 %d \n", dap_data->mb[i].value.val_bool);
            }

            if (dap_data->mb[i].key == 107)
            {
                // dap_data->mb[i].type = 0;
                dap_data->mb[i].value.val_bool = open_tu;
                printf("灌溉开关 %d \n", dap_data->mb[i].value.val_bool);
            }

            if (dap_data->mb[i].key == 108)
            {
                // dap_data->mb[i].type = 0;
                dap_data->mb[i].value.val_bool = open_fei;
                printf("施肥开关 %d \n", dap_data->mb[i].value.val_bool);
            }
            
        }
        sleep(2);
        shm_write(&sh, dap_data, sizeof(*dap_data));
    }
}
// 控制线程
void *kongzhi()
{
    while (1)
    {
        msg_queue_recv("daxianmuxiaoxi", &k_open, sizeof(k_open), 2, 0); // 收取消息队列的消息

        printf("********************:%d\n",k_open.kongzhi.key);

        if (k_open.kongzhi.key == 104) // 判断key值 来判断控制的那个开关
        {
            if (strcmp(k_open.kongzhi.value,"1")==0) // 判断bool值来判断开关的开还是关
            {
                modbus_write_bit(ctx, 0, 1);
            }
            else if (strcmp(k_open.kongzhi.value,"0")== 0)
            {
                modbus_write_bit(ctx, 0, 0);
            }
        }

        if (k_open.kongzhi.key == 105)
        {
            if (strcmp(k_open.kongzhi.value,"1")==0) // 判断bool值来判断开关的开还是关
            {
                modbus_write_bit(ctx, 1, 1);
            }
            else if (strcmp(k_open.kongzhi.value,"0")== 0)
            {
                modbus_write_bit(ctx, 1, 0);
            }
        }

        if (k_open.kongzhi.key == 106)
        {
            if (strcmp(k_open.kongzhi.value,"1")==0) // 判断bool值来判断开关的开还是关
            {
                modbus_write_bit(ctx, 2, 1);
            }
            else if (strcmp(k_open.kongzhi.value,"0")== 0)
            {
                modbus_write_bit(ctx, 2, 0);
            }
        }

        if (k_open.kongzhi.key == 107)
        {
            if (strcmp(k_open.kongzhi.value,"1")==0) // 判断bool值来判断开关的开还是关
            {
                modbus_write_bit(ctx, 3, 1);
            }
            else if (strcmp(k_open.kongzhi.value,"0")== 0)
            {
                modbus_write_bit(ctx, 3, 0);
            }
        }

        if (k_open.kongzhi.key == 108)
        {
           if (strcmp(k_open.kongzhi.value,"1")==0) // 判断bool值来判断开关的开还是关
            {
                modbus_write_bit(ctx, 4, 1);
            }
            else if (strcmp(k_open.kongzhi.value,"0")== 0)
            {
                modbus_write_bit(ctx, 4, 0);
            }
        }
        sleep(2);
    }
}

int main(int argc, char const *argv[])
{

    // 建立modbus实例
    ctx = modbus_new_tcp("192.168.51.49", 502);
    if (ctx == NULL)
    {
        perror("tcp err");
        return -1;
    }

    // 设置从机id
    modbus_set_slave(ctx, 1);

    // 建立链接
    if (modbus_connect(ctx) < 0)
    {
        perror("connect err");
        return -1;
    }
    printf("connect ok\n");

    pthread_t tid;
    pthread_create(&tid, NULL, caiji, NULL);
    pthread_t tid1;
    pthread_create(&tid1, NULL, kongzhi, NULL);

    while (1)
        ;

    return 0;
}
